/* Copyright 2007 Gearbox Software - http://www.gearboxsoft.com
 
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at
 
     http:www.apache.org/licenses/LICENSE-2.0
 
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.*/
namespace GearBlog.Web.Controllers
{
	using System;
	using System.Collections.Specialized;
	using System.IO;
	using System.Web;
	using Castle.MonoRail.Framework;
	using GearBlog.Web.ConfigSections;
	using GearBlog.Web.Filters;
	using GearBlog.Web.Helpers;
	using GearBlog.Web.Models;
	using GearBlog.Web.Services;
	using GearBlog.Web.Utils;

	[AuthenticationFilter(typeof(FormsAuthenticationAgent),RequiresLogin =false)]
	public class FileStoreController:ExtendedControllerBase
	{
		public void Upload(string storageKey,HttpPostedFile fileUpload)
		{
			const int bufferSize = 1024;
			FileUploadComponentSection section = FileUploadComponentSection.GetSection();
			Storage storage = section.Storages[storageKey];

			if (storage != null)
				if (IsAllowed(storage))
				{
					FileUploadStatus status=new FileUploadStatus(Context.UnderlyingContext.Session.SessionID);
					status.FileSize = fileUpload.ContentLength;

					status.Save();

					string fileTitle = Path.GetFileName(fileUpload.FileName);
					string fileName = string.Format(@"{0}\{1}\{2}", Context.ApplicationPhysicalPath, storage.Path, fileTitle);
					FileStream writeStream = new FileStream(fileName, FileMode.Create);
					BinaryWriter writer = new BinaryWriter(writeStream);
					BinaryReader reader = new BinaryReader(fileUpload.InputStream);

					while (status.TotalBytesRead != status.FileSize)
					{
						Byte[] buffer = new byte[bufferSize];
						int bytesRead = reader.Read(buffer, 0, bufferSize);

						status.AddBytesRead(bytesRead);

						writer.Write(buffer, 0, bytesRead);

						System.Threading.Thread.Sleep(10);
					}

					reader.Close();
					writer.Close();

					KillAjaxUpdate();

					status.Delete();
				}
		}

		private void KillAjaxUpdate()
		{
			RenderText(
				@"<html> 
					<head> 
					<script type='text/javascript'>function killUpdate() {
						window.parent.killUpdate(); 
					} </script> 
					</head>
					<body onload='killUpdate();'>Upload Completed </body> 
				</html>");
		}

		private bool IsAllowed(Storage storage)
		{
			if (!string.IsNullOrEmpty(storage.AllowedRolesString))
			{
				if (!IsUserAllowed(storage.GetAllowedRoles()))
				{
					AccessDenied();
					return false;
				}
				else
					return true;
			}
			else
				return true;
		}

		private bool IsUserAllowed(string[] allowedRoles)
		{
			if (CurrentUser == null && allowedRoles.Length > 0) return false;
			foreach (string role in allowedRoles)
			{
				if (CurrentUser.IsInRole(role))
					return true;
			}
			return false;
		}

		private void AccessDenied()
		{
			Response.StatusCode = 403;// Access Denied
			RenderText("Access Denied");

		}
		/*
		public void UploadSWF(string storageKey, HttpPostedFile fileData)
		{
			CancelView();
			const int bufferSize = 1024;
			FileUploadComponentSection section = FileUploadComponentSection.GetSection();
			Storage storage = section.Storages[storageKey];


			if (storage != null)
				if (IsAllowed(storage))
				{
				
					string fileTitle = Path.GetFileName(fileData.FileName);
					string fileName = string.Format(@"{0}\{1}\{2}", Context.ApplicationPhysicalPath, storage.Path, fileTitle);
					FileStream writeStream = new FileStream(fileName, FileMode.Create);
					BinaryWriter writer = new BinaryWriter(writeStream);
					BinaryReader reader = new BinaryReader(fileData.InputStream);

					int totalBytesRead = 0;
					while (totalBytesRead != fileData.ContentLength)
					{
						Byte[] buffer = new byte[bufferSize];
						int bytesRead = reader.Read(buffer, 0, bufferSize);

						totalBytesRead += bytesRead;

						writer.Write(buffer, 0, bytesRead);
					}

					reader.Close();
					writer.Close();
				}
		}
		 */

		public void ShowUpload()
		{

		}

		public void List(string storageKey,string view, string layout)
		{	
			RefreshList(storageKey);

			LayoutName = layout;

			PropertyBag["fileListView"] = view;
			RenderSharedView(GetFullFileListView(view,false));
			
		}

		private void RefreshList(string storageKey)
		{
			IFileStorageService service = ServiceContainer.Resolve<IFileStorageService>();

			string[] files = service.GetFiles(storageKey, Context);
				
			StringCollection fileList=new StringCollection();

			foreach (string fileName in files)
				fileList.Add(fileName);

			PropertyBag["fileList"] = fileList;
			PropertyBag["storageKey"] = storageKey;
		}
		private static string GetFullFileListView(string view, bool withExtension)
		{
			string formatString = "common/filelist/{0}" + (withExtension ? ".vm":"");

			return string.Format(formatString, view);

		}
		public void DeleteFile(string storageKey, string fileTitle, string view)
		{
			Storage storage = FileUploadComponentSection.GetSection().Storages[storageKey];

			if (storage!=null)
			{
				string path = Path.Combine(Path.Combine(Context.ApplicationPhysicalPath, storage.Path), fileTitle);
				if (File.Exists(path))
				{
					File.Delete(path);
					PropertyBag["message"] = "File deleted successfully.";
				}
				else
					PropertyBag["message"] = "File not exist.";

				PropertyBag["fileListView"] = view;
				PropertyBag["fullFileListView"] = GetFullFileListView(view, true);

				RefreshList(storageKey);

			}
		}
		public void ShowUploadStats()
		{
			Context.UnderlyingContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
			Context.UnderlyingContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
			Context.UnderlyingContext.Response.Cache.SetNoStore();
			Context.UnderlyingContext.Response.Cache.SetNoServerCaching();
			Context.UnderlyingContext.Response.Cache.SetExpires(DateTime.Now);  

			CancelView();

			FileUploadStatus status = FileUploadStatus.FindBySessionId(Context.UnderlyingContext.Session.SessionID);
			string message="Uploading...";
			if (status != null)
				message = string.Format("{0}/{1} Bytes", status.TotalBytesRead, status.FileSize);
			RenderText(message);
				
		}

	}
	
}
